package com.ilikesoup.instant.monitor.core;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class CglibBeanMonitor extends BeanMonitor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        ChangeEventTrigger changeEventTrigger;
        if (monitorMethodSupport != null && (changeEventTrigger = monitorMethodSupport.findTrigger(method)) != null) {
            Object oldVal = null;
            Invocation invocation = new Invocation(monitorContext, obj, method, args);
            try {
                oldVal = changeEventTrigger.copyOldValue(invocation);
                if (!Modifier.isAbstract(method.getModifiers())) {
                    invocation.setRetVal(proxy.invokeSuper(obj, args));
                }
            } finally {
                changeEventTrigger.fireChange(invocation, oldVal, propertyChangeSupport);
            }
            return invocation.getRetVal();
        } else {
            if (!Modifier.isAbstract(method.getModifiers())) {
                return proxy.invokeSuper(obj, args);
            }
        }
        return null;
    }

}
